/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package technotheist.geo.graph;

import com.jme3.math.Plane;
import com.jme3.math.Vector3f;
import gnu.trove.map.TLongObjectMap;

/**
 *
 * @author Mitch
 */
public class HalfEdge<Vertex extends GeoNode, Face extends GeoNode> {

    public final long ID;
    protected final Vertex origin;
    protected final Vertex target;
    protected final Face face;
    HalfEdge<Vertex, Face> symm;
    private HalfEdge<Vertex, Face> next;
    HalfEdge<Face, Vertex> left;
//    private final GeoGrid grid;
    private final Plane plane;

    public HalfEdge(Vertex origin, Vertex target, Face face) {
//        this.grid = grid;
        this.origin = origin;
        this.target = target;
        this.face = face;
        this.ID = EdgeID(origin.ID(), target.ID());
        this.plane = new Plane();
        plane.setPlanePoints(Vector3f.ZERO, origin.pos, target.pos);
    }

    void initSymm(TLongObjectMap<HalfEdge<Vertex, Face>> eList) {

        eList.put(ID, this);
        symm = eList.get(EdgeID(target.ID(), origin.ID()));
        if (symm != null) {
            symm.checkSymm();
        }
    }

    public Vertex origin() {
        return origin;
    }

    public Vertex target() {
        return target;
    }

    public Vector3f targetPos() {
        return target.pos;
    }

    public Vector3f originPos() {
        return origin.pos;
    }

    public HalfEdge<Vertex, Face> symm() {
        return symm;
    }

    public float distance(Vector3f pt) {
        return plane.pseudoDistance(pt);
    }

    public Plane.Side side(Vector3f pt) {
        return plane.whichSide(pt);
    }

    public static long EdgeID(int origin, int target) {
        return (((long) origin) << 32) | target;
    }

    public static long SwapID(long id) {
        return (id << 32) | (id >> 32);
    }

    public static int IDtoOrigin(long id) {
        return (int) (id >> 32);
    }

    public static int IDtoTarget(long id) {
        return (int) (id & 0xffffffff);
    }

    private void checkSymm() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}
